package com.core.framework.tools;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.core.framework.web.EasyResource;

public class ClassTools {
	/**
	 * 是否开启开发模式
	 */
	private static boolean devMode=Tools.getYesNo(EasyResource.getProString("easy.devMode","NO"));
    private static ClassTools classTools;
    private static String  _BasePackage = EasyResource.getProString("easy.scanPackage","");
    /**
     * 扫描类的过滤条件  如果配置文件中没有过滤条件 那么默认扫描所有类
     */
    private static String _ClassFilter = EasyResource.getProString("easy.service.Filter","*");
    private Set<Class<?>> classSet ;
    /**
     * 扫描时是否排出内部类
     */
    private static boolean excludeInner = true;
    /**
     * checkInOrEx：过滤规则适用情况 true—>搜索符合规则的 false->排除符合规则的<br>
     */
    private static boolean checkInOrEx = true;
    
    synchronized public static  ClassTools getClassTools()
    {
    	if(classTools==null)
    	{
    		classTools = new ClassTools();
    	}
    	if(devMode)
    	{
    		return new ClassTools();
    	}
    	return classTools;
    }
    synchronized public static  ClassTools getClassTools(boolean _excludeInner , boolean _checkInOrEx)
    {
    	if(classTools==null)
    	{
    		classTools = new ClassTools( _excludeInner , _checkInOrEx);
    	}
    	if(devMode)
    	{
    		return new ClassTools( _excludeInner , _checkInOrEx);
    	}
    	return classTools;
    }
	public ClassTools ()
	{
		classSet = ClassTools.getClassSet(_BasePackage);
	}
	public ClassTools (boolean _excludeInner , boolean _checkInOrEx)
	{
		excludeInner  = _excludeInner ;
		checkInOrEx = _checkInOrEx;
		classSet = ClassTools.getClassSet(_BasePackage);
	}
	//synchronized  是否同步 在考虑 TODO
	public  static  Set<Class<?>> getClassSet(String packageName)
    {
		// 自定义过滤规则
        List<String> classFilters = ClassTools.getClassFilter(_ClassFilter);
        // 创建一个扫描处理器，排除内部类 扫描符合条件的类
        ClassPathScanHandler handler = new ClassPathScanHandler(excludeInner, checkInOrEx,classFilters);
        Set<Class<?>> classAllSet = new   HashSet<Class<?>> ();
        if(StringUtils.isNotBlank(packageName))
        {
	        String[] pClassSet =  packageName.split(",");
	        for(String path : pClassSet)
	        {
	        	Set<Class<?>> classSet = handler.getPackageAllClasses(path, true);
	        	for(Class<?> cla : classSet )
	        	{
	        		classAllSet.add(cla);
	        	}
	        }
        }
    	return classAllSet;
    }
	public static  String[]  getPackageNameList(String packageNames )
	{
		String[] pStr = packageNames.split(",");
		return pStr;
	}
    /**
     * 获取ClassFilter 集合
     * @param classFilter
     * @return
     */
    private static  List<String> getClassFilter(String classFilter)
    {
    		
    	String[] filters = classFilter.split(",");
    	List<String> filterList = new ArrayList<String>();
    	for(String filter : filters)
    	{
    		filterList.add(filter);
    	}
    	return filterList;
    }

	public Set<Class<?>> getClassSet() {
		return classSet;
	}
	/**
	 * 获取指定注解的ClassSet
	 * @param annCla
	 * @return
	 */
	public Set<Class<?>> getClassSetByAnnotation(Class<? extends Annotation> annCla) {
		Set<Class<?>> annClassSet = new HashSet<Class<?>>();
		for(Class<?> cla : ClassTools.getClassTools().getClassSet())
		{
			if(cla.isAnnotationPresent(annCla))
			{
				annClassSet.add(cla);
			}
		}
		
		return annClassSet;
	}
	public void setClassSet(Set<Class<?>> classSet) {
		this.classSet = classSet;
	}
	public static void main(String[] args)
    {
		 ClassTools.getClassTools().getClassSetByAnnotation(Service.class);
		 for(Class<?> cla : ClassTools.getClassTools().getClassSetByAnnotation(Service.class))
		 {
			 Service name = (Service) cla.getAnnotation(Service.class);
			 String funcName = name.value();
			 System.out.println(cla.getName()+"---"+funcName);
		 }
//		for(Class<?> cla : ClassTools.getClassTools().getClassSet())
//		{
//			System.out.println("--"+cla.getName()+"");
//			if(cla.isAnnotationPresent(Service.class))
//			{
//				Service name = (Service) cla.getAnnotation(Service.class);
//				String funcName = name.value();
//				System.out.println(funcName);
//				Field fields[] = cla.getFields();
//			    for (Field f : fields) {
//                    if (f.getAnnotation(FtlField.class) != null) {
//                    	try {
//							System.out.println(f.getName()+">>>>>>>"+f.get(cla));
//						} catch (IllegalArgumentException e) {
//							e.printStackTrace();
//						} catch (IllegalAccessException e) {
//							e.printStackTrace();
//						}
//                    }
//                }
//			}
//		}
    }
}
